package com.zzcoder.mall.security.component;

import com.zzcoder.mall.common.exception.VerifyCodeException;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Data
@Component
public class VerifyCodeAuthenticationProvider extends DaoAuthenticationProvider {
    @Value("${secure.verify-code.enabled}")
    private boolean verifyCodeEnabled;

    @Value("${secure.verify-code.param-key}")
    private String paramKey;

    public VerifyCodeAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.setUserDetailsService(userDetailsService);
        this.setPasswordEncoder(passwordEncoder);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws VerifyCodeException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (!verifyCodeEnabled || checkVerifyCode(request, paramKey)) {
            return super.authenticate(authentication);
        }
        throw new VerifyCodeException("验证码错误");
    }

    /**
     * 验证码校验
     *
     * @param request
     * @return
     */
    private boolean checkVerifyCode(HttpServletRequest request, String key) {
        //获取生成的验证码
        String expect = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        //获取用户输入的验证码
        String actual = getUserInput(request, key);
        if (actual == null || !actual.equals(expect)) {
            return false;
        }
        return true;
    }

    /**
     * 将获取到的前端参数转为string类型
     *
     * @param request
     * @param key
     * @return
     */
    private String getUserInput(HttpServletRequest request, String key) {
        try {
            String result = request.getParameter(key);
            if (result != null) {
                result = result.trim();
            }
            if ("".equals(result)) {
                result = null;
            }
            return result;
        } catch (Exception e) {
            return null;
        }
    }
}
